<template>
  <div ref="container" class="canvas-container">
    <!-- 加载状态提示 -->
<!--    <div v-if="loading" class="loading">模型加载中...{{ progress }}%</div>-->

    <!-- 信息弹窗 -->
    <div v-if="tooltip.visible"
         class="tooltip"
         :style="{
           left: `${tooltip.x}px`,
           top: `${tooltip.y}px`
         }">
      <h3>{{ tooltip.title }}</h3>
      <p>{{ tooltip.content }}</p>
    </div>
  </div>
</template>

<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass'
import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { Sky } from 'three/examples/jsm/objects/Sky.js'

export default {
  name: 'FactoryModel',
  data() {
    return {
      // Three.js核心组件
      scene: null,
      camera: null,
      renderer: null,
      controls: null,

      // 后处理相关
      composer: null,
      outlinePass: null,

      // 状态管理
      loading: false,
      progress: 0,
      selectedObject: null,  // 当前选中对象

      // 弹窗配置
      tooltip: {
        visible: false,
        x: 0,
        y: 0,
        title: '设备信息',
        content: ''
      },
      mouseDownTime: 0,
      mouseDownPos: new THREE.Vector2(),
      isDragging: false,

      // 天空相关
      sky: null,
      sun: new THREE.Vector3(),
      skyParams: {
        turbidity: 10,
        rayleigh: 3,
        mieCoefficient: 0.005,
        mieDirectionalG: 0.7,
        elevation: 10,
        azimuth: 180,
        exposure: 1
      }
    }
  },
  mounted() {
    this.initScene()
    this.loadModel()
    this.setupEventListeners()
    this.animate()
  },
  beforeDestroy() {
    this.cleanupResources()
  },
  methods: {
    initScene() {
      this.scene = new THREE.Scene()
      this.scene.background = new THREE.Color(0xcccccc)

      this.camera = new THREE.PerspectiveCamera(
        45,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
      )
      this.camera.position.set(0, 100, 100)

      this.renderer = new THREE.WebGLRenderer({
        antialias: true,
        logarithmicDepthBuffer: true
      })
      this.renderer.setPixelRatio(window.devicePixelRatio)
      this.renderer.setSize(window.innerWidth, window.innerHeight)
      this.$refs.container.appendChild(this.renderer.domElement)

      this.initPostProcessing()
      this.addBasicLights()

      this.controls = new OrbitControls(this.camera, this.renderer.domElement)
      this.controls.enableDamping = true
      this.controls.dampingFactor = 0.05

      this.addSky()
    },

    addSky() {
      this.sky = new Sky()
      this.sky.scale.setScalar(450000)
      this.scene.add(this.sky)

      this.updateSunPosition()

      const skyUniforms = this.sky.material.uniforms
      skyUniforms['turbidity'].value = this.skyParams.turbidity
      skyUniforms['rayleigh'].value = this.skyParams.rayleigh
      skyUniforms['mieCoefficient'].value = this.skyParams.mieCoefficient
      skyUniforms['mieDirectionalG'].value = this.skyParams.mieDirectionalG
      skyUniforms['sunPosition'].value.copy(this.sun)

      this.renderer.toneMapping = THREE.ACESFilmicToneMapping
      this.renderer.toneMappingExposure = this.skyParams.exposure
    },

    updateSunPosition() {
      const phi = THREE.MathUtils.degToRad(90 - this.skyParams.elevation)
      const theta = THREE.MathUtils.degToRad(this.skyParams.azimuth)
      this.sun.setFromSphericalCoords(1, phi, theta)

      if (this.directionalLight) {
        this.directionalLight.position.copy(this.sun)
      }

      if (this.sky) {
        this.sky.material.uniforms['sunPosition'].value.copy(this.sun)
      }
    },

    initPostProcessing() {
      this.composer = new EffectComposer(this.renderer)
      const renderPass = new RenderPass(this.scene, this.camera)
      this.composer.addPass(renderPass)

      this.outlinePass = new OutlinePass(
        new THREE.Vector2(window.innerWidth, window.innerHeight),
        this.scene,
        this.camera
      )
      this.outlinePass.edgeStrength = 3.0
      this.outlinePass.edgeGlow = 0.5
      this.outlinePass.edgeThickness = 2.0
      this.outlinePass.pulsePeriod = 2
      this.outlinePass.visibleEdgeColor.set(0x00ffff)
      this.outlinePass.hiddenEdgeColor.set(0x0000ff)
      this.composer.addPass(this.outlinePass)
    },

    addBasicLights() {
      const ambientLight = new THREE.AmbientLight(0xffffff, 1)
      this.scene.add(ambientLight)

      this.directionalLight = new THREE.DirectionalLight(0xffffff, 1.5)
      this.directionalLight.position.copy(this.sun)
      this.scene.add(this.directionalLight)
    },

    loadModel() {
      this.loading = true
      const loader = new GLTFLoader()

      loader.load(
        '/demo/宁海模型3.gltf', // 确保路径正确
        (gltf) => {
          console.log('模型层级结构:', gltf.scene)
          console.log('动画列表:', gltf.animations)
          console.log('材质列表:', gltf.materials)
          const model = gltf.scene
          model.scale.set(0.1, 0.1, 0.1)

          // model.traverse(child => {
          //   if (child.isMesh) {
          //     child.userData = {
          //       name: child.name || '未命名部件',
          //       info: '设备状态：正常'
          //     }
          //   }
          // })

          this.scene.add(model)
          this.autoCameraPosition(model)
          this.loading = false
        },
        (xhr) => {
          this.progress = Math.round((xhr.loaded / xhr.total) * 100)
        },
        (error) => {
          console.error('模型加载失败:', error)
          this.loading = false
        }
      )
    },

    handleClick(event) {
      if (this.isDragging || this.controls.isRotating || this.controls.isPanning) {
        return
      }

      const moveThreshold = 5
      const deltaX = Math.abs(event.clientX - this.mouseDownPos.x)
      const deltaY = Math.abs(event.clientY - this.mouseDownPos.y)

      if (deltaX > moveThreshold || deltaY > moveThreshold) {
        return
      }

      const mouse = new THREE.Vector2()
      const rect = this.renderer.domElement.getBoundingClientRect()

      mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1
      mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1

      const raycaster = new THREE.Raycaster()
      raycaster.setFromCamera(mouse, this.camera)

      const intersects = raycaster.intersectObjects(this.scene.children, true)

      if (intersects.length > 0) {
        const selected = intersects[0].object

        if (this.selectedObject !== selected) {
          this.selectedObject = selected
          this.outlinePass.selectedObjects = [selected]
          this.showTooltip(selected, event)
        }
      } else {
        this.clearSelection()
      }
    },

    showTooltip(object, event) {
      this.tooltip = {
        visible: true,
        x: event.clientX + 15,
        y: event.clientY + 15,
        title: object.userData.name || '设备信息',
        content: object.userData.info || '暂无详细信息'
      }
    },

    clearSelection() {
      this.selectedObject = null
      this.outlinePass.selectedObjects = []
      this.tooltip.visible = false
    },

    autoCameraPosition(model) {
      const box = new THREE.Box3().setFromObject(model)
      const center = box.getCenter(new THREE.Vector3())
      const size = box.getSize(new THREE.Vector3()).length()

      const fitDistance = size * 1.5
      this.camera.position.copy(center).add(new THREE.Vector3(0, 0, fitDistance))
      this.camera.lookAt(center)

      this.controls.target.copy(center)
      this.controls.maxDistance = fitDistance * 3
    },

    onWindowResize() {
      this.camera.aspect = window.innerWidth / window.innerHeight
      this.camera.updateProjectionMatrix()
      this.renderer.setSize(window.innerWidth, window.innerHeight)
      this.composer.setSize(window.innerWidth, window.innerHeight)
    },

    animate() {
      requestAnimationFrame(this.animate)
      this.controls.update()
      this.composer.render()

      if (this.selectedObject) {
        const vector = new THREE.Vector3()
        this.selectedObject.getWorldPosition(vector)
        vector.project(this.camera)

        const x = (vector.x * 0.5 + 0.5) * window.innerWidth
        const y = (vector.y * -0.5 + 0.5) * window.innerHeight

        this.tooltip.x = x + 15
        this.tooltip.y = y + 15
      }
    },

    cleanupResources() {
      window.removeEventListener('resize', this.onWindowResize)
      const canvas = this.renderer.domElement
      canvas.removeEventListener('mousedown', this.handleMouseDown)
      canvas.removeEventListener('mousemove', this.handleMouseMove)
      canvas.removeEventListener('mouseup', this.handleMouseUp)
      canvas.removeEventListener('click', this.handleClick)

      this.renderer.dispose()
      this.composer.passes.forEach(pass => pass.dispose())
      this.$refs.container.removeChild(this.renderer.domElement)
    },

    setupEventListeners() {
      window.addEventListener('resize', this.onWindowResize)
      const canvas = this.renderer.domElement
      canvas.addEventListener('mousedown', this.handleMouseDown)
      canvas.addEventListener('mousemove', this.handleMouseMove)
      canvas.addEventListener('mouseup', this.handleMouseUp)
      canvas.addEventListener('click', this.handleClick)
    },

    handleMouseDown(event) {
      this.mouseDownTime = Date.now()
      this.mouseDownPos.set(event.clientX, event.clientY)
      this.isDragging = false
    },

    handleMouseMove() {
      if (Date.now() - this.mouseDownTime > 50) {
        this.isDragging = true
      }
    },

    handleMouseUp() {
      this.isDragging = false
    },
  }
}
</script>

<style scoped>
/* 原有样式保持不变 */
.canvas-container {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  position: relative;
}

.loading {
  position: absolute;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  color: white;
  background: rgba(0,0,0,0.7);
  padding: 8px 16px;
  border-radius: 4px;
  font-family: Arial;
  z-index: 100;
}

.tooltip {
  position: fixed;
  background: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 12px;
  border-radius: 6px;
  pointer-events: none;
  min-width: 200px;
  max-width: 300px;
  z-index: 100;
  backdrop-filter: blur(2px);
  border: 1px solid rgba(255,255,255,0.1);
  box-shadow: 0 4px 12px rgba(0,0,0,0.25);
}

.tooltip h3 {
  margin: 0 0 8px 0;
  font-size: 16px;
  color: #00ffff;
}

.tooltip p {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
}
</style>